using System;

namespace Bookvar.ObjectModel.Actions
{
    /// <summary>
    /// A base class for actions that work on a topic and mind map.
    /// </summary>
    public abstract class MindmapTopicActionBase : TopicActionBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="MindmapTopicActionBase"/> class.
        /// </summary>
        protected MindmapTopicActionBase()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MindmapTopicActionBase"/> class.
        /// </summary>
        /// <param name="topic">The <see cref="Topic"/> for this action.</param>
        /// <param name="mindmap">The <see cref="ObjectModel.MindMap"/> for this action.</param>
        /// <exception cref="ArgumentNullException">
        /// if <paramref name="mindmap"/> or <paramref name="topic"/> is null;
        /// </exception>
        protected MindmapTopicActionBase( Topic topic, MindMap mindmap ) : base( topic )
        {
            if ( mindmap == null ) throw new ArgumentNullException( "mindmap" );

            Mindmap = mindmap;
        }

        /// <summary>
        /// Executes (or redoes) the logic for the action.
        /// </summary>
        /// <exception cref="InvalidOperationException">if <see cref="Mindmap"/> is null.</exception>
        public override void Execute()
        {
            if ( mindmap == null )
            {
                throw new InvalidOperationException( "Could not execute the action without a mind map." );
            }

            base.Execute();
        }

        /// <summary>
        /// Undoes the action.
        /// </summary>
        /// <exception cref="InvalidOperationException">if the <see cref="Mindmap"/> for this action is not set;
        /// or if Undo is called before the action is executed.</exception>
        public override void Undo()
        {
            base.Undo();

            if ( mindmap == null )
            {
                throw new InvalidOperationException( "Could not undo the action without a mind map." );
            }
        }

        private MindMap mindmap;

        /// <summary>
        /// Gets or sets the <see cref="ObjectModel.MindMap"/>for this action.
        /// </summary>
        /// <value>The mindmap.</value>
        /// <exception cref="ArgumentNullException">if value is null.</exception>
        public MindMap Mindmap
        {
            get { return mindmap; }
            set
            {
                if(value == null) throw  new ArgumentNullException("value");

                mindmap = value;
            }
        }
    }
}
